# coding:utf-8
# writingtime: 2022-7-6
# author:wanjun
import os
from Utilities.AutoGetOperator.selectPackage import get_func

root_path = os.path.realpath(os.path.dirname(os.path.dirname(__file__)))  # 项目的根目录
project_path = os.path.join(root_path, r'Operators\OperationOperators')  # 项目所在目录
file_a_path = os.path.join(project_path, 'OperatorIVQROF.py')  # 目标文件目录
Operator_IVQ_ROFS=get_func(r'Operators/OperationOperators/OperatorIVQROF.py','Operator_IVQ_ROFS')

class MABAC(Operator_IVQ_ROFS):
    def __init__(self,matrix,weight_list=[],q=3,gangliang=[]):
        '''
        function: MABAC决策方法
        :param matrix: 决策矩阵
        :param weight_list: 属性权重
        :param q: q值
        :param gangliang: 成本型或效益型表示，成本型用0表示，效益型用1表示
        '''
        super(MABAC,self).__init__(q=q)
        self.q=q
        self.matrix = matrix
        if len(weight_list):
            self.weight_list = weight_list
        else:
            self.weight_list = [1/len(matrix[0]) for i in range(len(matrix[0]))]
        # 检测是否传入纲量，若未传入，则全默认为效益型属性
        if len(gangliang):
            self.gangliang=gangliang
        else:
            self.gangliang=[1 for i in range(len(matrix[0]))]
        # 获得方案的最大最小
        self.postive,self.negative=self.get_positive_negative()
        # 获得标准化矩阵
        self.normalizedMatrix=self.getNormalizedMatrix()
        # 获得加权标准化矩阵
        self.weightedNormalizedMatrix=self.getWeightedNormalizedMatrix()
        # 获得边缘向量
        self.borderMatrix=self.getBorderMatrix()
        # 获得与边缘矩阵的距离
        self.distanceBorder=self.getDistanceBorder()
        # 检测是否传入权重，若未传入，则初始值为1/n（n为属性的个数）


    def get_positive_negative(self):
        '''
        function: 获取没个方案中的最大最小值
        :return: 最大最小值的向量
        '''

        score_matrix=[[self.getsco(j,self.q).getScore() for j in i ] for i in self.matrix]
        temp=[[score_matrix[i][j] for i in range(len(score_matrix))]for j in range(len(score_matrix[0]))]
        # 获得最大值与最小值的下标
        max_index=[i.index(max(i)) for i in temp]
        min_index=[i.index(min(i)) for i in temp]
        return max_index,min_index

    def getNormalizedMatrix(self):
        '''
        function: 根据最大最小值，将矩阵中的元素标准化
        :return: 标准化矩阵
        '''
        normalizedMatrix=[]
        for i in range(len(self.matrix)):
            li=[]
            for j in range(len(self.matrix[0])):
                temp_up=self.subtract(self.matrix[i][j],self.matrix[self.negative[j]][j],self.q)
                temp_down=self.subtract(self.matrix[self.postive[j]][j],self.matrix[self.negative[j]][j],self.q)
                temp=self.divid(temp_up,temp_down,self.q)
                li.append(temp)
            normalizedMatrix.append(li)

        return normalizedMatrix

    def getWeightedNormalizedMatrix(self):
        '''
        function：计算加权标准化矩阵，原公式为r_ij=w_j+(r_ij)*(w_j)，现修改为r_ij=(r_ij)*(w_j)
        :return: 加权标准化矩阵
        '''
        weightedNormailedMatrix=[[self.kmulti(self.normalizedMatrix[i][j],self.weight_list[j],self.q)
                                 for j in range(len(self.matrix[0]))] for i in range(len(self.matrix))]

        return weightedNormailedMatrix

    def getBorderMatrix(self):
        '''
        function: 计算边缘向量
        :return: 边缘向量
        '''
        borderMatrix=[]
        for j in range(len(self.matrix[0])):
            temp=self.matrix[0][j]
            for i in range(1,len(self.matrix)):
                temp=self.multi(temp,self.matrix[i][j],self.q)
            temp=self.pow(temp,1/len(self.matrix),self.q)
            borderMatrix.append(temp)

        return borderMatrix

    def getDistanceBorder(self):
        '''
        function: 计算与边缘向量的距离
        :return:
        '''
        distanceMatrix=[]
        for i in range(len(self.weightedNormalizedMatrix)):
            li=[]
            for j in range(len(self.weightedNormalizedMatrix[0])):
                temp=self.subtract(self.weightedNormalizedMatrix[i][j],self.borderMatrix[j],self.q)
                li.append(temp)
            distanceMatrix.append(li)

        return distanceMatrix

    def getResultList(self):
        '''
        function: 计算方案与边缘面积的总近似距离
        :return:
        '''
        totalValue=[]
        for i in range(len(self.matrix)):
            temp=self.distanceBorder[i][0]
            for j in range(1,len(self.matrix[0])):
                temp=self.add(temp,self.distanceBorder[i][j],self.q)
            totalValue.append(temp)

        return totalValue

    def getResult(self):
        '''
        function: 计算方案得分
        :return:
        '''
        value=self.getResultList()
        result=[self.getsco(i,self.q).getScore() for i in value]
        # result=[i/sum(result) for i in result]
        return result



if __name__=='__main__':
    li=[
       [([0.81539, 0.91785], [0.17128, 0.28772]), ([0.12374, 0.22949], [0.55729, 0.67911]), ([0.84635, 0.95753], [0.10662, 0.21768]), ([0.73433, 0.90407], [0.20174, 0.23691]),],
       [([0.79202, 0.84776], [0.10917, 0.11366]), ([0.29818, 0.3131], [0.47785, 0.64139]), ([0.14316, 0.29861], [0.78271, 0.8032]), ([0.01997, 0.33824], [0.71369, 0.85874]),  ],
       [([0.89511, 0.90987], [0.1782, 0.21547]), ([0.19584, 0.25518], [0.4043, 0.51519]), ([0.24707, 0.43495], [0.71766, 0.74854]), ([0.08338, 0.28006], [0.1259, 0.34247]),   ],
       [([0.09222, 0.1264], [0.78533, 0.81673]), ([0.24999, 0.31601], [0.63687, 0.7492]), ([0.13707, 0.23335], [0.75133, 0.88383]), ([0.70681, 0.77778], [0.00605, 0.18418]),  ],
       [([0.1876, 0.28807], [0.42117, 0.57172]), ([0.1311, 0.19959], [0.7644, 0.81178]), ([0.06145, 0.20426], [0.86783, 0.89045]), ([0.74275, 0.86356], [0.14231, 0.25652])  ]
      ]

    a=MABAC(li,[.2,.2,.3,.3,],3)
    # print(a.add(([0.85, 0.95], [0.1, 0.2]), ([0.8, 0.9], [0.1, 0.2])))
    # print(a.getResultList())
    print(a.getResult())

